home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1991 …esperately Seeking Seven / Desperately Seeking Seven.2mg / Dev.CD.8 / Essentials / Tools / File.Type.Notes / FTN.E0.8002 < prev    next >
Encoding:
Text File  |  1990-07-23  |  49.7 KB  |  935 lines  |  [04] ASCII Text (0x0000)

  1. Apple II
  2. File Type Notes
  3. _____________________________________________________________________________
  4.                                                   Developer Technical Support
  5.  
  6. File Type:         $E0 (224)
  7. Auxiliary Type:    $8002
  8.  
  9. Full Name:     NuFile Exchange Archival Library
  10. Short Name:    ShrinkIt (NuFX) document
  11.  
  12. Revised by:    Andy Nicholas and Matt Deatherage                    July 1990
  13. Written by:    Matt Deatherage                                      July 1989
  14.  
  15. Files of this type and auxiliary type contain NuFX Archival Libraries.
  16. Changes since July 1989:  Rewrote major portions to reflect Master Version 
  17. $0002 of the NuFX standard.
  18. _____________________________________________________________________________
  19.  
  20. Introduction
  21.  
  22. NuFX is a robust, full-featured archival standard for the Apple II family.  
  23. The standard, as presented in this Note, allows for full archival of ProDOS 
  24. and GS/OS files while keeping all file attributes with each file, as well as 
  25. providing necessary archival functions such as multiple compression schemes 
  26. and multiple archival implementations of the same standard.  NuFX is 
  27. implemented in the application ShrinkIt, a free archival utility program for 
  28. enhanced IIe, IIc and IIgs computers.  (Versions for earlier Apple II models 
  29. are also available.)
  30.  
  31. The NuFX standard was developed by Andrew Nicholas for Paper Bag Productions.  
  32. Comments or suggestions on the NuFX standard, or comments and suggestions on 
  33. ShrinkIt are welcome at:
  34.  
  35.                     Paper Bag Productions
  36.                     8415 Thornberry Drive East
  37.                     Upper Marlboro, MD  20772
  38.                     Attn:  NuFX Technical Support
  39.                     America Online:    ShrinkIt
  40.                     GEnie:    ShrinkIt
  41.                     CompuServe:    70771,2615
  42.  
  43.  
  44. History
  45.  
  46. The Apple II community has always lacked a well-defined method for archiving 
  47. files.  NuFX is an attempt to rectify the situation by providing a flexible, 
  48. consistent standard for archiving files, disks, and other computer media.  
  49. Although many files are archived using the Binary II standard (see Apple II 
  50. File Type Note, File Type $E0, Auxiliary Type $8000), it was not designed as 
  51. an archival standard and its continued use as such creates problems.  More 
  52. people are using Binary II as an archival standard than as a way to keep 
  53. attributes with a file when transferred, and this use is causing the original 
  54. intent of Binary II to become lost and unused.
  55.  
  56. NuFX, developed as an archival standard for the days of GS/OS, allows:
  57.  
  58.   o  Filenames longer than 64 characters (GS/OS can create 8,000-
  59.      character filenames).
  60.   o  A convenient way to add to, remove from, and work on an archive.
  61.   o  Including GS/OS files which contain resource forks.
  62.   o  Including entire disk images.
  63.   o  Including comments with a file.
  64.   o  A convenient way to represent a file compressed or encrypted by a 
  65.      specific application.
  66.   o  A true archive standard.  Binary IIs original intent was to make 
  67.      transfer of Apple II files from local machines to large 
  68.      information services possible; otherwise, a file's attribute 
  69.      information would be lost.  Use of Binary II to archive files 
  70.      rather than simply maintain their attributes stretches it beyond 
  71.      its original intent.
  72.  
  73. Adding all of these features to the existing Binary II standard would be 
  74. nearly impossible without violating the existing standard and causing a great 
  75. deal of confusion.  Although Binary II is flexible, it is simply unable to 
  76. address all of these concerns without alienating existing Binary II extraction 
  77. programs.
  78.  
  79. To provide some differentiation between standards and provide a better 
  80. functioning format, this Note presents a new standard called NuFX (NuFile 
  81. eXchange for the Apple II; pronounced new-F-X).  NuFX fixes the problems that 
  82. Apple IIgs users would soon be experiencing as other filing systems become 
  83. available for GS/OS.  NuFX attempts to stem a set of problems before they have 
  84. a chance to develop.  NuFX provides all of the features of Binary II, but goes 
  85. further to allow the user the ultimate in flexibility, usefulness and 
  86. performance.
  87.  
  88.  
  89. Additional Date/Time Data type:
  90.  
  91. Date/Time (8 Bytes):
  92.  
  93. +000    second    Byte    The second, 0 through 59.
  94. +001    minute    Byte    The minute, 0 through 59.
  95. +002    hour      Byte    The hour, 0 through 23.
  96. +003    year      Byte    The current year minus 1900.
  97. +004    day       Byte    The day, 0 through 30.
  98. +005    month     Byte    The month, 0 through 11 (0 = January).
  99. +006    filler    Byte    Reserved, must be zero.
  100. +007    weekDay   Byte    The day of the week, 1 through 7 (1 = Sunday).
  101.  
  102. The format of the Date/Time field is identical to that described for the 
  103. ReadTimeHex call in the Apple IIgs Toolbox Reference Manual.
  104.  
  105.  
  106. Implementation
  107.  
  108. Figure 1 illustrates the basic structure of a NuFX archive.
  109.  
  110.                     |     First Record      |      Next Record      |
  111.      _______________|_______________________|_______________________|
  112.     | Master Header | Header |     Data     | Header |     Data     |
  113.     |_______________|________|______________|________|______________|
  114.  
  115.                     Figure 1-NuFX Archive Structure
  116.  
  117. A single master header block contains values which describe the entire archive 
  118. (those with knowledge of structured programming may consider them archive 
  119. globals).  Each of the succeeding header blocks contains only information 
  120. about the record it precedes (consider each an archive local).
  121.  
  122. Each header block is followed by a list of threads, which is followed by the 
  123. actual threads.  The data for each thread may be a data fork, resource fork, 
  124. message, control sequence for a NuFX utility program, or almost any kind of 
  125. sequential data.
  126.  
  127. Possible Block Combinations:
  128.  
  129. The blocks must occur in the following fashion:
  130.  
  131.     Master Header Block containing N entries
  132.  
  133.     Header Block
  134.     Threads list:
  135.         filename_thread (16 bytes)
  136.         message_thread (16 bytes)
  137.         data thread (16 bytes)
  138.         .
  139.         .
  140.         .
  141.     filename_thread's data (filename_thread's comp_thread_eof # of bytes)
  142.     message_thread's data (message_thread's comp_thread_eof # of bytes)
  143.     data_thread's data (data_thread's comp_thread_eof # of bytes)
  144.     .
  145.     .
  146.     .
  147.     Next Header Block (notice no second Master Header block)
  148.     Threads list (message, control, data or resource)
  149.     .
  150.     .
  151.     .
  152.     Nth Header Block
  153.     Threads list (message, control, data or resource)
  154.  
  155. Master Header Block Contents
  156.  
  157. +000    nufile_id      6 Bytes    These six bytes spell the word "NuFile" in 
  158.                                   alternating ASCII (low, then high) for 
  159.                                   uniqueness.  The six bytes are $4E $F5 $46 
  160.                                   $E9 $6C $E5.
  161. +006    master_crc     Word       A 16-bit cyclic redundancy check 
  162.                                   (CRC) of the remaining fields in this 
  163.                                   block (bytes +008 through +047).  Any 
  164.                                   programs which modify the master header 
  165.                                   block must recalculate the CRC for the 
  166.                                   master header.  (see the section "A Sample 
  167.                                   CRC Algorithm")  The initial value of this 
  168.                                   CRC is $0000.
  169. +008    total_records  Long       The total number of records in this 
  170.                                   archive file.  It is possible to chain 
  171.                                   multiple records (files or disks) 
  172.                                   together, as it is possible to chain 
  173.                                   different types of records together (mixed 
  174.                                   files and disks).
  175. +012    archive_create_when
  176.                        Date/Time  The date and time on which this archive 
  177.                                   was initially created.  This field should 
  178.                                   never be changed once initially written.  
  179.                                   If the date is not known, or is unable to 
  180.                                   be calculated, this field should be set to 
  181.                                   zero.  If the weekday is not known, or is 
  182.                                   unable to be calculated, this field should 
  183.                                   be set to null.
  184. +020    archive_mod_when
  185.                        Date/Time  The date of the last modification to this 
  186.                                   archive.  This field should be changed 
  187.                                   every time a change is made to any of the 
  188.                                   records in the archive.  If the date is 
  189.                                   not known, or is unable to be calculated, 
  190.                                   this field should be set to zero.  If the 
  191.                                   weekday is not known, or is unable to be 
  192.                                   calculated, this field should be set to 
  193.                                   null.
  194. +028    master_version
  195.                        Word       The master version number of the NuFX 
  196.                                   archive.  This Note describes 
  197.                                   master_version $0002, for which the next 
  198.                                   eight bytes are zeroed.
  199. +030    reserved       8 Bytes    Must be null ($00000000).
  200. +038    master_eof     Long       The length of the NuFX archive, in 
  201.                                   bytes.  Any programs which modify the 
  202.                                   length of an archive, either increasing it 
  203.                                   or decreasing it in size, must change this 
  204.                                   field in the master header to reflect the 
  205.                                   new size.
  206.  
  207. Header Block Contents:
  208.  
  209. Following the Master Header block is a regular Header Block, which precedes 
  210. each record within the NuFX archive.  A cyclic redundancy check (CRC) has been 
  211. provided to detect archives which have possibly been corrupted.  The only time 
  212. the CRC should be included in a block is for the Master Header and for each of 
  213. the regular Header Blocks.  The CRC ensures reliability and data integrity.
  214.  
  215. +000    nufx_id        4 Bytes    These four bytes spell the word "NuFX" in 
  216.                                   alternating ASCII (low, then high) for 
  217.                                   uniqueness.  The four bytes are $4E $F5 
  218.                                   $46 $D8.
  219. +004    header_crc     Word       The 16-bit CRC of the remaining 
  220.                                   fields of this block (bytes +006 through 
  221.                                   the end of the header block and any 
  222.                                   threads following it).  This field is used 
  223.                                   to verify the integrity of the rest of the 
  224.                                   block.  Programs which create NuFX 
  225.                                   archives must include this in every 
  226.                                   header.  It is up to the discretion of the 
  227.                                   extracting program to check the validity 
  228.                                   of this CRC.  Any programs which might 
  229.                                   modify the header of a particular record 
  230.                                   must recalculate the CRC for the header 
  231.                                   block.  The initial value for this CRC is 
  232.                                   zero ($0000).
  233. +006    attrib_count   Word       This field describes the length of 
  234.                                   the attribute section of each record in 
  235.                                   bytes.  This count measures the distance 
  236.                                   in bytes from the first field (offset 
  237.                                   +000) up to and including the 
  238.                                   filename_length field.  By convention, the 
  239.                                   filename_length field will always be the 
  240.                                   last 2 bytes of the attribute section 
  241.                                   regardless of what has preceded it.
  242. +008    version_number
  243.                        Word       Version of this record.  If version_number 
  244.                                   is $0000, no option_list fields are 
  245.                                   present.  If the version_number is $0001 
  246.                                   option_list fields may be present.  If the 
  247.                                   version_number is $0002 then option_list 
  248.                                   fields may be present and a valid CRC-16 
  249.                                   exists for the compressed data in the data 
  250.                                   threads of this record.  If the 
  251.                                   version_number is $0003 then option_list 
  252.                                   fields may be present and a valid CRC-16 
  253.                                   exists for the uncompressed data in the 
  254.                                   data threads of this record.  The current 
  255.                                   version number is $0003 and should always 
  256.                                   be used when making archives.
  257. +010    total_threads  Long       The number of thread subrecords 
  258.                                   which should be expected immediately 
  259.                                   following the filename or pathname at the 
  260.                                   end of this header block.  This field is 
  261.                                   extremely important as it contains the 
  262.                                   information about the length of the last 
  263.                                   third of the header.
  264. +014    file_sys_id    Word       The native file system identifier:
  265.                                       $0000    reserved
  266.                                       $0001    ProDOS/SOS
  267.                                       $0002    DOS 3.3
  268.                                       $0003    DOS 3.2
  269.                                       $0004    Apple II Pascal
  270.                                       $0005    Macintosh HFS
  271.                                       $0006    Macintosh MFS
  272.                                       $0007    Lisa File System
  273.                                       $0008    Apple CP/M
  274.                                       $0009    reserved, do not use (The 
  275.                                                GS/OS Character FST returns 
  276.                                                this value)
  277.                                       $000A    MS-DOS
  278.                                       $000B    High Sierra
  279.                                       $000C    ISO 9660
  280.                                       $000D    AppleShare
  281.                                       $000E-$FFFF    Reserved, do not use
  282.                                   If the file system of a disk being 
  283.                                   archived is not known, it should be set to 
  284.                                   zero.
  285. +016    file_sys_info  Word       Information about the current filing 
  286.                                   system.  The low byte of this word (offset 
  287.                                   +016) is the native file system separator.  
  288.                                   For ProDOS, this is the slash (/ or $2F).  
  289.                                   For HFS and GS/OS, the colon (: or $3F) is 
  290.                                   used, and for MS-DOS, the separator is the 
  291.                                   backslash (\ or $5C).  This separator is 
  292.                                   provided so archival utilities may know 
  293.                                   how to parse a valid file or pathname from 
  294.                                   the filename field for the receiving file.  
  295.                                   GS/OS archival utilities should not 
  296.                                   attempt to parse pathnames, as it is not 
  297.                                   possible to build in syntax rules for file 
  298.                                   systems not currently defined.  Instead, 
  299.                                   pass the pathname directory to GS/OS and 
  300.                                   attempt translation (asking the user for 
  301.                                   suggestions) only if GS/OS returns an 
  302.                                   "Invalid Path Name Syntax" error.  The 
  303.                                   high byte of this word is reserved and 
  304.                                   should remain zero.
  305. +018    access         Flag Long      Bits 31-8    reserved, must be zero
  306.                                       Bit 7 (D)    1 = destroy enabled
  307.                                       Bit 6 (R)    1 = rename enabled
  308.                                       Bit 5 (B)    1 = file needs to be 
  309.                                                    backed up
  310.                                       Bits 4-3    reserved, must be zero
  311.                                       Bit 2 (I)    1 = file is invisible
  312.                                       Bit 1 (W)    1 = write enabled
  313.                                       Bit 0 (R)    1 = read enabled
  314. +022    file_type      Long       The file type of the file being archived.  
  315.                                   For ProDOS 8 or GS/OS, this field should 
  316.                                   always be what the operating system 
  317.                                   returns when asked.  For disks being 
  318.                                   archived, this field should be zero.
  319. +026    extra_type     Long       The auxiliary type of the file being 
  320.                                   archived.  For ProDOS 8 or GS/OS, this 
  321.                                   field should always be what the operating 
  322.                                   system returns when asked.  For disks 
  323.                                   being archived, this field should be the 
  324.                                   total number of blocks on the disk.
  325. +030    storage_type   Word       For Files:  The storage type of the 
  326.                                   file.  Types $1 through $3 are standard 
  327.                                   (one-forked) files, type $5 is an extended 
  328.                                   (two-forked) file, and type $D is a 
  329.                                   subdirectory.
  330.         file_sys_block_size
  331.                        Word       For Disks:  The block size used by the 
  332.                                   device should be placed in this field.  
  333.                                   For example, under ProDOS, this field will 
  334.                                   be 512, while for HFS it might be 524.  
  335.                                   The GS/OS Volume call will return this 
  336.                                   information if asked.
  337. +032    create_when    Date/Time  The date and time on which 
  338.                                   this record was initially created.  If the 
  339.                                   creation date and time are available from 
  340.                                   a disk device, this information should be 
  341.                                   included.  If the date is not known, or is 
  342.                                   unable to be calculated, this field should 
  343.                                   be set to zero.  If the weekday is not 
  344.                                   known, or is unable to be calculated, this 
  345.                                   field should be set to zero.
  346. +040    mod_when       Date/Time  The date and time on which this record was 
  347.                                   last modified.  If the modification date 
  348.                                   and time are available from a disk device, 
  349.                                   this information should be included.  If 
  350.                                   the date is not known, or is unable to be 
  351.                                   calculated, this field should be set to 
  352.                                   zero.  If the weekday is not known, or is 
  353.                                   unable to be calculated, this field should 
  354.                                   be set to zero.
  355. +048    archive_when   Date/Time  The date and time on which 
  356.                                   this record was placed in this archive.  
  357.                                   If the date is not known, or is unable to 
  358.                                   be calculated, this field should be set to 
  359.                                   zero.  If the weekday is not known, or is 
  360.                                   unable to be calculated, this field should 
  361.                                   be set to zero.
  362.  
  363. The following option_list information is only present if the NuFX version 
  364. number for this record is $0001 or greater.
  365.  
  366. +056    option_size    Word       The length of the FST-specific 
  367.                                   portion of a GS/OS option_list returned by 
  368.                                   GS/OS.  This field may be $0000, 
  369.                                   indicating the absence of a valid 
  370.                                   option_list.
  371.  
  372. A GS/OS option_list is formatted as follows:
  373.  
  374.         +000           buffer_size
  375.                        Word       Size of the buffer for GS/OS to 
  376.                                   place the option_list in, including 
  377.                                   this count word.  This must be at 
  378.                                   least $2E.
  379.         +002           list_size
  380.                        Word       The number of bytes of information 
  381.                                   returned by GS/OS.
  382.         +004           file_sys_ID
  383.                        Word       A file system ID word (see list 
  384.                                   above) identifying the FST owning 
  385.                                   the file in question.
  386.         +006           option_bytes
  387.                        Bytes      The bytes returned by the FST.  
  388.                                   There are (buffer_size - 6) of them.
  389.  
  390. The option_list contains information specific to native file systems that 
  391. GS/OS doesn't normally use (such as true creator_type, file_type, and access 
  392. privileges for AppleShare).  Other FSTs released in the future will follow 
  393. similar conventions to return native file system specific parameters in the 
  394. option_list.  Information in the option_list should always be copied from file 
  395. to file.
  396.  
  397. The value option_size in the NuFX header is the value of list_size minus two.  
  398. Immediately following the option_size count word are (list_size - 2) bytes.  
  399. To pass these values back to the destination file system, construct an 
  400. option_list with a suitably large buffer_size, a list_size of the NuFX 
  401. option_size + 2, the file_sys_id of the source file, and the FST-returned 
  402. option_bytes.
  403.  
  404. +058    list_bytes     Bytes      FST-specific bytes returned in an 
  405.                                   option_list.  These are the bytes in the 
  406.                                   GS/OS option_list not including the FST ID 
  407.                                   word.  There are option_size of them.  If 
  408.                                   option_size is an odd number, one zero 
  409.                                   byte of padding is added to keep the block 
  410.                                   size an even number.
  411.  
  412. Because the attributes section does not have a fixed size, the next field must 
  413. be found by looking two bytes before the offset indicated by attrib_count 
  414. (+006).
  415.  
  416. +attrib_count - 2
  417.         filename_length
  418.                        Word       Obsolete, should be set to zero.  In 
  419.                                   previous versions of NuFX, this field was 
  420.                                   the length of a file name or pathname 
  421.                                   immediately following this field.
  422.  
  423.                                   To allow the inclusion of future 
  424.                                   additional parameters in the attributes 
  425.                                   section, NuFX utility programs should rely 
  426.                                   on the attribs_count field to find the 
  427.                                   filename_length field.
  428.  
  429.                                   Current convention is to zero this field 
  430.                                   when building an archive and put the file 
  431.                                   or pathname into a filename thread so the 
  432.                                   record can be renamed in the archive.  
  433.                                   Archival programs should recognize both 
  434.                                   methods to find a valid file name or 
  435.                                   pathname.
  436. +attrib_count
  437.         filename       Bytes      Filename or partial pathname if 
  438.                                   applicable.  If this is a disk being 
  439.                                   archived, then the volume_name should be 
  440.                                   included in this field.  If a volume name 
  441.                                   is included in this field, a separator 
  442.                                   should not be included in, or precede the 
  443.                                   name.  If a volume name is not available, 
  444.                                   then this field should be zeros.
  445.  
  446.                                   If a partial pathname is specified, the 
  447.                                   directories to which the current pathname 
  448.                                   refers need not have preceded this 
  449.                                   particular record.  The extraction program 
  450.                                   must test each referenced directory 
  451.                                   individually.  If the directory in 
  452.                                   question does not exist, the extracting 
  453.                                   program should create it.
  454.  
  455.                                   Any utility which extracts file from a 
  456.                                   NuFX archive must not assume that this 
  457.                                   field will be in a format it is able to 
  458.                                   handle.  In particular, extraction 
  459.                                   programs should check for syntax 
  460.                                   unacceptable to the operating system under 
  461.                                   which they run and perform whatever 
  462.                                   conversions are necessary to parse a legal 
  463.                                   filename or pathname.  In general, assume 
  464.                                   nothing.  (GS/OS programs should pass the 
  465.                                   filename or pathname directly to GS/OS, 
  466.                                   and only attempt to convert the name if 
  467.                                   GS/OS returns an "invalid pathname syntax" 
  468.                                   error.)
  469.  
  470.                                   Both high and low ASCII values are valid 
  471.                                   but may not mean the same to each file 
  472.                                   system (for example, all eight bits are 
  473.                                   significant in AppleShare pathnames while 
  474.                                   only seven are significant in ProDOS 
  475.                                   pathnames).
  476.  
  477.  
  478. Threads
  479.  
  480. Thread Records are 16-byte records which immediately follow the Header Block 
  481. (composed of the attributes and file name of the current record) and describe 
  482. the types of data structures which are included with a given record.  The 
  483. number of Thread Records is described in the attribute section by a Word, 
  484. total_threads.
  485.  
  486. Each Thread Record should be checked for the type of information that a given 
  487. utility program can extract.  If a utility is incapable of extracting a 
  488. particular thread, that thread should be skipped (with the exception of 
  489. extended files under ProDOS 8, which should be dearchived into AppleSingle 
  490. format, or both threads should be skipped).  If a utility finds a redundancy 
  491. in a Thread Record, it must decide whether to skip the record or to do 
  492. something with that particular thread (i.e., if a utility finds two 
  493. message_thread threads it can either ignore the second one or display it.  
  494. Likewise, if a utility finds two data_thread threads for the same file, it 
  495. should inspect the thread_kind of each.  If they match, it can either 
  496. overwrite the first thread extracted, or warn the user and skip the second 
  497. thread).
  498.  
  499. Thread records can be represented as follows:
  500.  
  501. +000    thread_class   Word       The classification of the thread:
  502.                                       $0000    message_thread
  503.                                       $0001    control_thread
  504.                                       $0002    data_thread
  505.                                       $0003    filename_thread
  506. +002    thread_format  Word       The format of the data within the thread:
  507.                                       $0000    Uncompressed
  508.                                       $0001    Huffman Squeeze
  509.                                       $0002    Dynamic LZW/1 (ShrinkIt 
  510.                                                specific)
  511.                                       $0003    Dynamic LZW/2 (ShrinkIt 
  512.                                                specific)
  513.                                       $0004    Unix 12-bit Compress
  514.                                       $0005    Unix 16-bit Compress
  515. +004    thread_kind    Word       Describes the kind of data within 
  516.                                   the thread.
  517.  
  518. thread_kind must be interpreted on the basis of thread_class.  See the table 
  519. below for the currently defined thread_kind interpretations:
  520.  
  521.             class $0000  class $0001       class $0002            class $0003
  522.             -----------  ----------------  ---------------------  -----------
  523. kind $0000  ASCII text   create directory  data fork of file      filename
  524. kind $0001  see below    undefined         disk image             undefined
  525. kind $0002  see below    undefined         resource fork of file  undefined
  526.  
  527. +006    thread_crc     Word       For version_number $0003, this field 
  528.                                   is the CRC of the original data before it 
  529.                                   was compressed or otherwise transformed.  
  530.                                   The CRC-16's initial value is set to $FFFF.
  531. +008    thread_eof     Long       The length of the thread when uncompressed.
  532. +012    comp_thread_eof
  533.                        Long       The length of the thread when compressed.
  534.  
  535. Class $0000 with kind $0000 is obsolete and should not be used.
  536.  
  537. Class $0000 with kind $0001 has a predefined comp_thread_eof and a thread_eof 
  538. whose length may change.  This way, a certain amount of space may be allocated 
  539. when a record is created and edited later.
  540.  
  541. Class $0000 with kind $0002 is a standard Apple IIgs icon.  comp_thread_eof is 
  542. the length of the icon image; thread_eof is ignored.
  543.  
  544. Class $0003 with kind $0000 has a predefined comp_thread_eof and a thread_eof 
  545. whose length may change.  After this record is placed into the archive, the 
  546. thread_eof can be changed if the name is changed, but the length of the name 
  547. may not extend beyond the space allocated for it, comp_thread_eof.
  548.  
  549. A thread_format of $0001 indicates Huffman Squeeze.  NuFX's Huffman is the 
  550. same Huffman used  by ARC v5.x, SQ and USQ, the source of which is publicly 
  551. available and was originally written by Richard Greenlaw.  The first word of 
  552. the thread data is the number of nodes followed by the Huffman tree and the 
  553. actual data.  This is also the same algorithm decoded by the Apple II version 
  554. of USQ written by Don Elton.  The C source to this is widely available.
  555.  
  556. A thread_format of $0002 indicates a special variant of LZW (LZW/1) used by 
  557. ShrinkIt.  The first two bytes of this thread are a CRC-16 of the uncompressed 
  558. data within the thread.  This CRC-16 is initialized to zero ($0000). The third 
  559. byte is the low-level volume number used by the eight-bit version of ShrinkIt 
  560. to format 5.25" disks.  The fourth byte is the run-length character used to 
  561. decode the rest of the thread.  The data which comprises the compressed file 
  562. or disk immediately follows the RLE character.
  563.  
  564. When ShrinkIt compresses a file, it reads 4096-byte chunks of the file until 
  565. it reaches the file's EOF.  The last 4096-byte chunk is padded with zeroes if 
  566. the file's length is not an exact multiple of 4096.  Compressing a disk is 
  567. also done by reading sequential blocks of 4096-bytes.
  568.  
  569. Each 4K chunk is first compressed with RLE compression.  The RLE character is 
  570. determined by reading the fourth byte of the thread.  The RLE character which 
  571. is used by most current versions of ShrinkIt is $DB.  A run of characters is 
  572. represented by three bytes, consisting of the run character, the number of 
  573. characters in the run and the character in the run.  If the 4K chunk expands 
  574. after being compressed with RLE then the uncompressed 4K chunk is passed to 
  575. the LZW compressor. If the 4K chunk shrinks after being compressed with RLE 
  576. then the RLE-compressed image of the 4K chunk is passed to the LZW compressor.
  577.  
  578. ShrinkIt's LZW compressor individually compresses each 4K chunk passed to it 
  579. by using variable length (9 to 12 bits) codes.  The way that ShrinkIt's LZW 
  580. compressor functions is almost identical to the algorithm used in the public 
  581. domain utility Compress.  The first code is $0101.  The LZW string table is 
  582. cleared before compressing each 4K chunk.  If the compressed chunk increases 
  583. in size, then the previous 4K chunk (which may be run-length-encoded or just 
  584. uncompressed data) is written to the file.
  585.  
  586. The first word of every 4K chunk is aligned to a byte boundary within the file 
  587. and is the length which resulted from the attempt at compressing the chunk 
  588. with RLE.  If the value of this word is 4096, then RLE was not successful at 
  589. compressing the chunk.  A single byte follows the word and indicates whether 
  590. or not LZW was performed on this chunk.  A value of zero indicates that LZW 
  591. was not used, while a value of one indicates that LZW was used and that the 
  592. chunk must first be decompressed with LZW before doing any further processing.
  593.  
  594. To decompress a file, each 4K chunk must first be expanded if it was 
  595. compressed by LZW.  If the 4K chunk wasn't compressed with LZW, then the word 
  596. which appears at the beginning of each chunk must be used to determine if the 
  597. data for the current chunk needs to be processed by the run-length decoder.  
  598. If the value of the word is 4096, then run-length decoding does not need to 
  599. occur because the data is uncompressed.
  600.  
  601. If the word indicates that the length of the chunk after being decompressed by 
  602. LZW is 4096-bytes long, then no run-length decoding needs to take place.  If 
  603. value of the word is less than 4096 then the chunk must be run-length decoded 
  604. to 4096 bytes.
  605.  
  606. There are four varying degrees of compression which can occur with a chunk: it 
  607. can be uncompressed data.  It can be run-length-encoded data without LZW 
  608. compression.  It can also be uncompressed data on which RLE was attempted (but 
  609. failed) and then was subsequently compressed with LZW.  Or, finally, the chunk 
  610. can be compressed with RLE and then also compressed with LZW.
  611.  
  612. A thread_format of $0003 indicates a special variant of LZW (LZW/2) used by 
  613. ShrinkIt.  The first byte is the low-level volume number used by the eight-bit 
  614. version of ShrinkIt to format 5.25" disks.  The second byte is the run-length 
  615. character used to decode the rest of the thread.  The data which comprises the 
  616. compressed file or disk immediately follows the second byte of the thread.
  617.  
  618. The format of LZW/2 is almost the same as LZW/1 with a few exceptions.  Unlike 
  619. LZW/1, where the LZW string table is automatically cleared before each 4K 
  620. chunk is processed, the LZW string table used by LZW/2 is only cleared when 
  621. the table becomes full, indicating a change in the redundancy of the source 
  622. text.  Not clearing the string table almost always yields improved compression 
  623. ratios because the compressor's dictionary is not being depleted every 4K and 
  624. larger strings are allowed to accumulate. The clear code used by ShrinkIt is 
  625. $100.  Whenever the decompressor sees a $100 code, it must clear the string 
  626. table.
  627.  
  628. The string table is also cleared when the compressor has to "back track" 
  629. because a 4K chunk became larger.  Whenever a chunk that is not compressed by 
  630. LZW is seen by the decompressor, the LZW string table must be cleared.  Bits 
  631. 0-12 of the first word of each chunk in a LZW/2 thread indicate the size of 
  632. the chunk after being compressed with RLE.  The high bit (bit 15) indicates 
  633. whether or not LZW was used on the chunk.  If LZW was not used (bit 15 = 0), 
  634. the data for the chunk immediately follows the first word.  If LZW was used 
  635. (bit 15 = 1), a second word which is a count of the total number of bytes used 
  636. by the current chunk follows the first word.  The mark of the next chunk can 
  637. be found by taking the mark at the beginning of the current chunk and adding 
  638. the second word to it, using that as an offset for a ProDOS 8 or GS/OS SetMark 
  639. call.  This is not normally necessary because the next chunk is processed 
  640. immediately after the current chunk.
  641.  
  642. This second word is an improvement over LZW/1 because if a chunk becomes 
  643. corrupted, but the second word is valid, the next chunk can be found and most 
  644. of the file recovered.  The second word is not needed (and not present) when 
  645. LZW is not used on the chunk because the first word is also a count of the 
  646. number of bytes which follow that word.
  647.  
  648. A thread_format of $0004 indicates that a maximum of 12 bits per LZW code by 
  649. Compress was used to build this thread.  The actual thread data contains 
  650. Compress's usual three-byte signature, the third byte of which contains the 
  651. actual number of bits per LZW code that was actually used.  The number of bits 
  652. may be less than or equal to 12.  Optimally, this requires (at 12 bits) a 16K 
  653. hash table to decode and should be used only for transferring to machines with 
  654. limited amounts of memory.  The C source to Compress is in the public domain 
  655. and is widely available.
  656.  
  657. A thread_format of $0005 indicates that a maximum of 16 bits per LZW code by 
  658. Compress was used to build this thread.  The actual thread data contains 
  659. Compress's usual three-byte signature, the third byte of which contains the 
  660. actual number of bits per LZW code that was actually used.  The number of bits 
  661. may be less than or equal to 16.  Optimally, this requires (at 16 bits) a 256K 
  662. hash table to decode.  The C source to Compress is in the public domain and is 
  663. widely available.
  664.  
  665. If a control_thread indicates that a directory should be created on the 
  666. destination device, the path to be created must take the form of a ProDOS 
  667. partial pathname.  That is, the path must not be preceded with a volume name.  
  668. For example, /Stuff/SubDir is an invalid path for this control_thread, while 
  669. SubDir/AnotherSubDir is valid.
  670.  
  671. If a control_thread indicates that a path is to be created, all subdirectories 
  672. that are contained in the pathname must be created.
  673.  
  674. control_thread threads will eventually be used to control the execution of 
  675. utility programs by allowing them to create, rename, and delete directories 
  676. and files and to move and modify files.  A form of scripting language will 
  677. eventually be able to allow utility programs to perform these actions 
  678. automatically.  control_thread threads will allow extraction programs to 
  679. perform operations similar to those of the Apple IIgs Installer, allowing 
  680. updates to program sets dependent on such things as creation or modification 
  681. dates and version numbers.
  682.  
  683.  
  684. Extra Information
  685.  
  686. If the file system of a particular disk is not known, the file_sys_id field 
  687. should be set to zero, the volume name should also be zeroed, and all the 
  688. other fields pertaining only to files should be set to zero.
  689.  
  690. If the file system of a particular disk is known, as many of the fields as 
  691. possible should be filled with the correct information.  Fields which do not 
  692. pertain to an archived disk should remain set to zero.
  693.  
  694. If an entire disk is added to the archive without some form of compression 
  695. (i.e., record_format = uncompressed), then the blocks which comprise the disk 
  696. image must be added sequentially from the first through the last block.  Since 
  697. there will be no character included in the data stream to mark the end or 
  698. beginning of a block, extraction programs should rely on the 
  699. file_sys_block_size field to determine how many bytes to read from the record 
  700. to properly fill a block.
  701.  
  702. Some Useful Thread Algorithms:
  703.  
  704. The beginning of the thread records can be found with the following algorithm:
  705.  
  706.     Threads := (mark at beginning of header) + (attrib_count) + 
  707.                (filename_length)
  708.  
  709. The end of the thread records can be found with the following algorithm:
  710.  
  711.     endOfThreads := Threads + (16 * total_threads)
  712.  
  713. The beginning of a data_thread can be found with the following formula:
  714.  
  715.     Data Mark := endOfThreads + (comp_thread_eof of all threads in the thread 
  716.                  list which are not data prior to finding a data_thread)
  717.  
  718. The beginning of a resource_thread may be found with the following algorithm:
  719.  
  720.     Resource Mark := endOfThreads + (comp_thread_eof of all threads in the 
  721.                      thread list which are not data prior to finding a 
  722.                      resource_thread)
  723.  
  724. The next record can be found using the following algorithm:
  725.  
  726.     Next Mark := endOfThreads + (comp_thread_eof of each thread)
  727.  
  728. The file name and its length can be found with the following algorithm:
  729.  
  730.     if (filename_length > 0)
  731.         then
  732.             length of filename is filename_length;
  733.             filename is found at attrib_count;
  734.         else
  735.             look through list of threads for a filename_thread;
  736.             if you find one, then length of filename is thread_eof;
  737.             if you don't find one, then you don't have a filename.
  738.  
  739.  
  740. Directories
  741.  
  742. Directories are handled almost the same way that normal files are handled with 
  743. the exception that there will be no data in the thread which follows the 
  744. entry.  A Thread Record must exist to inform a utility that a directory is to 
  745. be created through the use of the proper control_thread value.
  746.  
  747. Directories do not necessarily have to precede a record which references a 
  748. directory.  For example, if a record contains Stuff/MyStuff, the directory 
  749. Stuff need not exist for the extracting program to properly extract the 
  750. record.  The extracting program must check to see if each of the directories 
  751. referenced exist, and if one does not exist, create it.  While this method 
  752. places a great burden on the abilities of the extraction program, it avoids 
  753. the anomalies associated with the deletion of directories within an archive.
  754.  
  755.  
  756. A Sample CRC Algorithm
  757.  
  758. Paper Bag Productions provides the source code to a very fast routine which 
  759. does the CRC calculation as needed for NuFX archives.  The routine makeLookup 
  760. needs to be called only once.  After the first call, the routine doByte should 
  761. be called repeatedly with each new byte in succession to generate the 
  762. cumulative CRC for the block.  The CRC word should be reset to null ($0000) 
  763. before beginning each new CRC.
  764.  
  765. This is the same CRC calculation which is done for CRC/Xmodem and Ymodem.  The 
  766. code is easily portable to a 16-bit environment like the Apple IIgs.  The only 
  767. detrimental factor with this routine is that it requires 512 bytes of main 
  768. memory to operate.  If you can spare the space, this is one of the fastest 
  769. routines Paper Bag Productions knows to generate a CRC-16 on a 6502-type 
  770. machine.
  771.  
  772. The CRC word should be reset to $0000 for normal CRC-16 and to $FFFF before 
  773. generating the CRC on the unpacked data for each data thread.
  774.  
  775.  
  776. *-------------------------------
  777. * fast crc routine based on table lookups by
  778. * Andy Nicholas - 03/30/88 - 65C02 - easily portable to nmos 6502 also.
  779. * easily portable into orca/m format, just snip and save.
  780. * Modified for generic EDAsm type assemblers - MD 6/19/89
  781.  
  782.          X6502                          turn 65c02 opcodes on
  783.  
  784. *-------------------------------
  785. * routine to make the lookup tables
  786. *-------------------------------
  787.  
  788. makeLookup
  789.          LDX   #0                       zero first page
  790. zeroLoop STZ   crclo,x                  zero crc lo bytes
  791.          STZ   crchi,x                  zero crc hi bytes
  792.          INX
  793.          BNE   zeroLoop
  794.  
  795. *-------------------------------
  796. * the following is the normal bitwise computation
  797. * tweeked a little to work in the table-maker
  798.  
  799. docrc
  800.          LDX   #0                       number to do crc for
  801.  
  802. fetch    TXA
  803.          EOR   crchi,x                  add byte into high
  804.          STA   crchi,x                  of crc
  805.  
  806.          LDY   #8                       do 8 bits
  807. loop     ASL   crclo,x                  shift current crc-16 left
  808.          ROL   crchi,x
  809.          BCC   loop1
  810.  
  811. * if previous high bit wasn't set, then don't add crc
  812. * polynomial ($1021) into the cumulative crc.  else add it.
  813.  
  814.          LDA   crchi,x                  add hi part of crc poly into
  815.          EOR   #$10                     cumulative crc hi
  816.          STA   crchi,x
  817.  
  818.          LDA   crclo,x                  add lo part of crc poly into
  819.          EOR   #$21                     cumulative crc lo
  820.          STA   crclo,x
  821. loop1    DEY                            do next bit
  822.          BNE   loop                     done? nope, loop
  823.  
  824.          INX                            do next number in series (0-255)
  825.          BNE   fetch                    didn't roll over, so fetch more
  826.          RTS                            done
  827.  
  828. crclo    ds    256                      space for low byte of crc table
  829. crchi    ds    256                      space for high bytes of crc table
  830.  
  831.  
  832. *-------------------------------
  833. * do a crc on 1 byte/fast
  834. * on initial entry, CRC should be initialized to 0000
  835. * on entry, A = byte to be included in CRC
  836. * on exit, CRC = new CRC
  837. *-------------------------------
  838.  
  839. doByte
  840.          EOR   crc+1                    add byte into crc hi byte
  841.          TAX                            to make offset into tables
  842.  
  843.          LDA   crc                      get previous lo byte back
  844.          EOR   crchi,x                  add it to the proper table entry
  845.          STA   crc+1                    save it
  846.  
  847.          LDA   crclo,x                  get new lo byte
  848.          STA   crc                      save it back
  849.  
  850.          RTS                            all done
  851.  
  852. crc      dw    0000                     cumulative crc for all data
  853.  
  854. The following CRC check is written in APW assembler format for an Apple IIgs 
  855. with 16-bit memory and registers on entry.
  856.  
  857. crcByte  start
  858.  
  859. crc      equ         $0
  860. crca     equ         $2
  861. crcx     equ         $4
  862. crctemp  equ         $6
  863.  
  864.          sta         crca                                                 4
  865.          stx         crcx                                                 4
  866.  
  867.          eor         crc+1              on entry, number to add to CRC    4
  868.          and         #$00ff             is in (A)                         3
  869.          asl         a                                                    2
  870.          tax                                                              2
  871.          lda         crc16Table,x                                         5
  872.          and         #$00ff                                               3
  873.          sta         crcTemp                                              4
  874.  
  875.          lda         crc-1                                                4
  876.          eor         crc16Table,x                                         5
  877.          and         #$ff00                                               3
  878.          ora         crcTemp                                              4
  879.          sta         crc                                                  4
  880.  
  881.          lda         crca                                                 4
  882.          ldx         crcx                                                 4
  883.          rts                                                    cycles = 59
  884.  
  885.  
  886. ;
  887. ; CRC-16 Polynomial = $1021
  888. ;
  889. crc16table anop
  890.          dc    i'$0000, $1021, $2042, $3063, $4084, $50a5, $60c6, $70e7'
  891.          dc    i'$8108, $9129, $a14a, $b16b, $c18c, $d1ad, $e1ce, $f1ef'
  892.          dc    i'$1231, $0210, $3273, $2252, $52b5, $4294, $72f7, $62d6'
  893.          dc    i'$9339, $8318, $b37b, $a35a, $d3bd, $c39c, $f3ff, $e3de'
  894.          dc    i'$2462, $3443, $0420, $1401, $64e6, $74c7, $44a4, $5485'
  895.          dc    i'$a56a, $b54b, $8528, $9509, $e5ee, $f5cf, $c5ac, $d58d'
  896.          dc    i'$3653, $2672, $1611, $0630, $76d7, $66f6, $5695, $46b4'
  897.          dc    i'$b75b, $a77a, $9719, $8738, $f7df, $e7fe, $d79d, $c7bc'
  898.          dc    i'$48c4, $58e5, $6886, $78a7, $0840, $1861, $2802, $3823'
  899.          dc    i'$c9cc, $d9ed, $e98e, $f9af, $8948, $9969, $a90a, $b92b'
  900.          dc    i'$5af5, $4ad4, $7ab7, $6a96, $1a71, $0a50, $3a33, $2a12'
  901.          dc    i'$dbfd, $cbdc, $fbbf, $eb9e, $9b79, $8b58, $bb3b, $ab1a'
  902.          dc    i'$6ca6, $7c87, $4ce4, $5cc5, $2c22, $3c03, $0c60, $1c41'
  903.          dc    i'$edae, $fd8f, $cdec, $ddcd, $ad2a, $bd0b, $8d68, $9d49'
  904.          dc    i'$7e97, $6eb6, $5ed5, $4ef4, $3e13, $2e32, $1e51, $0e70'
  905.          dc    i'$ff9f, $efbe, $dfdd, $cffc, $bf1b, $af3a, $9f59, $8f78'
  906.          dc    i'$9188, $81a9, $b1ca, $a1eb, $d10c, $c12d, $f14e, $e16f'
  907.          dc    i'$1080, $00a1, $30c2, $20e3, $5004, $4025, $7046, $6067'
  908.          dc    i'$83b9, $9398, $a3fb, $b3da, $c33d, $d31c, $e37f, $f35e'
  909.          dc    i'$02b1, $1290, $22f3, $32d2, $4235, $5214, $6277, $7256'
  910.          dc    i'$b5ea, $a5cb, $95a8, $8589, $f56e, $e54f, $d52c, $c50d'
  911.          dc    i'$34e2, $24c3, $14a0, $0481, $7466, $6447, $5424, $4405'
  912.          dc    i'$a7db, $b7fa, $8799, $97b8, $e75f, $f77e, $c71d, $d73c'
  913.          dc    i'$26d3, $36f2, $0691, $16b0, $6657, $7676, $4615, $5634'
  914.          dc    i'$d94c, $c96d, $f90e, $e92f, $99c8, $89e9, $b98a, $a9ab'
  915.          dc    i'$5844, $4865, $7806, $6827, $18c0, $08e1, $3882, $28a3'
  916.          dc    i'$cb7d, $db5c, $eb3f, $fb1e, $8bf9, $9bd8, $abbb, $bb9a'
  917.          dc    i'$4a75, $5a54, $6a37, $7a16, $0af1, $1ad0, $2ab3, $3a92'
  918.          dc    i'$fd2e, $ed0f, $dd6c, $cd4d, $bdaa, $ad8b, $9de8, $8dc9'
  919.          dc    i'$7c26, $6c07, $5c64, $4c45, $3ca2, $2c83, $1ce0, $0cc1'
  920.          dc    i'$ef1f, $ff3e, $cf5d, $df7c, $af9b, $bfba, $8fd9, $9ff8'
  921.          dc    i'$6e17, $7e36, $4e55, $5e74, $2e93, $3eb2, $0ed1, $1ef0'
  922.          end
  923.  
  924. Further Reference
  925. _____________________________________________________________________________
  926.   o  ProDOS 8 Technical Reference Manual
  927.   o  GS/OS Reference
  928.   o  Apple IIgs Toolbox Reference Manual
  929.   o  Apple II File Type Note, File Type $E0, Auxiliary Type $8000
  930.   o  Apple II Miscellaneous Technical Note #14, Guidelines for 
  931.      Telecommunication Programs
  932.   o  "A Technique for High-Performance Data Compression," T. Welch, 
  933.      IEEE Computer, Vol. 17, No.6, June 1984, pp. 8-19.
  934.  
  935.